package com.mdd.front.service.coupon.impl;

import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mdd.common.constant.GlobalConstant;
import com.mdd.common.core.PageResult;
import com.mdd.common.entity.code.CouponCode;
import com.mdd.common.entity.coupon.Coupon;
import com.mdd.common.entity.coupon.UserCoupon;
import com.mdd.common.entity.goods.Goods;
import com.mdd.common.entity.goods.GoodsSpecification;
import com.mdd.common.exception.OperateException;
import com.mdd.common.mapper.coupon.CouponCodeMapper;
import com.mdd.common.mapper.coupon.CouponMapper;
import com.mdd.common.mapper.coupon.UserCouponMapper;
import com.mdd.common.mapper.goods.GoodsMapper;
import com.mdd.common.mapper.specification.GoodsSpecificationMapper;
import com.mdd.common.utils.TimeUtil;
import com.mdd.front.service.album.impl.AlbumServiceImpl;
import com.mdd.front.service.coupon.ICouponService;
import com.mdd.front.service.goods.impl.GoodsServiceImpl;
import com.mdd.front.validate.PageParam;
import com.mdd.front.vo.coupon.CouponListVo;
import com.mdd.front.vo.goods.GoodsDetailVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ICouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> implements ICouponService {

	@Resource
	private UserCouponMapper userCouponMapper;

	@Resource
	private GoodsMapper goodsMapper;

	@Resource
	private CouponCodeMapper couponCodeMapper;

	@Resource
	private CouponMapper couponMapper;

	@Resource
	private GoodsSpecificationMapper goodsSpecificationMapper;
	@Autowired
	private AlbumServiceImpl albumServiceImpl;
	@Autowired
	private GoodsServiceImpl goodsServiceImpl;

	@Override
	public PageResult<CouponListVo> list(PageParam pageParam, Map<String, String> params) {
		Page<Coupon> couponPage = this.baseMapper.selectPage(new Page<Coupon>(pageParam.getPageNo(), pageParam.getPageSize()),
				new LambdaQueryWrapper<Coupon>()
						.eq(Coupon::getIsDelete, GlobalConstant.NOT_DELETE)
						.gt(Coupon::getEndTime, TimeUtil.timestamp())
						.eq(Coupon::getShareType, GlobalConstant.NOT_DELETE));
		ArrayList<CouponListVo> couponListVos = new ArrayList<>();
		couponPage.getRecords().forEach(coupon -> {
			CouponListVo vo = new CouponListVo();
			BeanUtils.copyProperties(coupon, vo);
			vo.setStartTime(TimeUtil.timestampToDate(coupon.getStartTime()));
			vo.setEndTime(TimeUtil.timestampToDate(coupon.getEndTime()));
			couponListVos.add(vo);
		});
		return PageResult.iPageHandle(couponPage.getTotal(), couponPage.getCurrent(), couponPage.getSize(), couponListVos);
	}

	@Override
	public void receiveCoupon(Integer id, Integer userId) {
		List<UserCoupon> userCoupons = userCouponMapper.selectList(new LambdaQueryWrapper<UserCoupon>()
				.eq(UserCoupon::getCouponId, id)
				.eq(UserCoupon::getUserId, userId)
				.eq(UserCoupon::getIsDelete, GlobalConstant.NOT_DELETE));
		if(userCoupons != null && !userCoupons.isEmpty()) {
			throw new OperateException("已有优惠券,不能重复领取");
		}
		// 领取优惠券
		setCouponData(userId, id);
	}

	/**
	 * @param goodsSpecificationId 服务id
	 * @param userId 用户id
	 * @return 返回列表
	 */
	@Override
	public List<CouponListVo> goodsCoupon(Integer goodsSpecificationId, Integer userId) {
		// 查询出当前用户没有使用的优惠券
		List<UserCoupon> userCoupons = userCouponMapper.selectList(new LambdaQueryWrapper<UserCoupon>()
				.eq(UserCoupon::getIsUsed, GlobalConstant.NOT_DELETE)
				.eq(UserCoupon::getUserId, userId));
		ArrayList<CouponListVo> couponListVos = new ArrayList<>();
		userCoupons.forEach(coupon -> {
			CouponListVo vo = new CouponListVo();
			// 获取优惠券的详细信息
			Coupon coupon1 = this.baseMapper.selectById(coupon.getCouponId());
			BeanUtils.copyProperties(coupon1, vo);
			vo.setStartTime(TimeUtil.timestampToDate(coupon1.getStartTime()));
			vo.setEndTime(TimeUtil.timestampToDate(coupon1.getEndTime()));

			GoodsSpecification goodsSpecification = goodsSpecificationMapper.selectOne(new LambdaQueryWrapper<GoodsSpecification>()
					.eq(GoodsSpecification::getIsDelete, GlobalConstant.NOT_DELETE)
					.eq(GoodsSpecification::getId, goodsSpecificationId));
			Goods goods = goodsMapper.selectById(goodsSpecification.getGoodsId());
			Long categoryId = goods.getCategoryId();

			if(coupon1.getUseRange() != null && Integer.parseInt(categoryId + "") == Integer.parseInt(coupon1.getUseRange() + "")) {
				vo.setUse(true);
			} else if(coupon1.getService() != null) {
				List<Long> collect = Arrays.stream(coupon1.getService().substring(1, coupon1.getService().length() - 1).split(",")).map(str -> {
					return Long.parseLong(str.trim());
				}).collect(Collectors.toList());
				if(collect.contains(goodsSpecification.getId())) {
					vo.setUse(true);
				}

				//.contains(goodsSpecification.getId() + "")
				// 判断商品是否在优惠券中
			} else {
				vo.setUse(false);
			}
			couponListVos.add(vo);
		});
		couponListVos.sort((o1, o2) -> {
			if(o1.getUse() && o2.getUse()) {
				if (o1.getAmount().compareTo(o2.getAmount()) < 0) {
					return 1;
				}
				return 0;
			} else if(o1.getUse())  {
				return -1;
			} else if(!o2.getUse()){
				return o1.getAmount().compareTo(o2.getAmount());
			}
			return 0;
		});
		return couponListVos;
	}

	@Override
	public void collectCoupon(String code, Integer userId) {
		LambdaQueryWrapper<CouponCode> couponCodeLambdaQueryWrapper = new LambdaQueryWrapper<>();
		couponCodeLambdaQueryWrapper.eq(CouponCode::getCouponCode, code);
		couponCodeLambdaQueryWrapper.eq(CouponCode::getIsUse, GlobalConstant.NOT_DELETE);
		CouponCode couponCode = couponCodeMapper.selectOne(couponCodeLambdaQueryWrapper);
		Assert.notNull(couponCode, "优惠码不存在");
		couponCode.setIsUse(GlobalConstant.DELETE);
		couponCodeMapper.updateById(couponCode);

		Integer imageId = couponCode.getImageId();
		albumServiceImpl.albumDel(Collections.singletonList(imageId));
		setCouponData(userId, couponCode.getCouponId());
	}
	@Override
	public PageResult<CouponListVo> getUserCoupon(PageParam pageParam, Integer userId, Integer type) {
		Page page = new Page(pageParam.getPageNo(), pageParam.getPageSize());
		// 根据类型来进行筛选已使用和未使用和全部
		LambdaQueryWrapper<UserCoupon> queryWrapper = new LambdaQueryWrapper<UserCoupon>()
				.eq(UserCoupon::getUserId, userId);
		if(type == 0) {
			queryWrapper.eq(UserCoupon::getIsUsed, GlobalConstant.NOT_DELETE);
		} else if(type == 1) {
			queryWrapper.eq(UserCoupon::getIsUsed, GlobalConstant.DELETE);
		} else if(type == 2) {
			queryWrapper.lt(UserCoupon::getEndTime, TimeUtil.timestamp());
		}
		queryWrapper.orderByDesc(UserCoupon::getCreateTime);

		Page<UserCoupon> page1 = userCouponMapper.selectPage(page, queryWrapper);
		ArrayList<CouponListVo> couponListVos = new ArrayList<>();
		page1.getRecords().stream().forEach(userCoupon -> {
			CouponListVo couponListVo = new CouponListVo();
			Coupon coupon = couponMapper.selectById(userCoupon.getCouponId());
			BeanUtils.copyProperties(userCoupon, couponListVo);
			BeanUtils.copyProperties(coupon, couponListVo);
			couponListVos.add(couponListVo);
		});

		return PageResult.iPageHandle(page1.getTotal(), page1.getCurrent(), page1.getSize(), couponListVos);
	}

	@Override
	public List<GoodsDetailVo> getGoodsByCouponId(Integer couponId) {
		Coupon coupon = this.baseMapper.selectById(couponId);
		// 获取规格的id
		String[] split = coupon.getService().substring(1, coupon.getService().length() - 1).split(",");
		// 获取规格的详情
		// 将goodsSpecificationMapper.selectBatchIds(Arrays.asList(split))查询出来的结果，通过字段goodsId来进行去重
		ArrayList<Long> integers = new ArrayList<>();
		goodsSpecificationMapper.selectBatchIds(Arrays.asList(split)).forEach(goodsSpecification -> {
			if(integers.contains(goodsSpecification.getGoodsId())) {
				return;
			}
			integers.add(goodsSpecification.getGoodsId());
		});
		List<Goods> goods = goodsMapper.selectBatchIds(integers);
		ArrayList<GoodsDetailVo> goodsDetailVos = new ArrayList<>();
		goods.forEach(goods1 -> {
			GoodsDetailVo goodsDetailVo = new GoodsDetailVo();
			BeanUtils.copyProperties(goods1, goodsDetailVo);
			goodsDetailVos.add(goodsDetailVo);
		});
		return goodsDetailVos;
	}

	@Override
	public Coupon getCouponByCouponCode(String couponCode, Integer couponId) {
		if(couponId != null) {
			return this.baseMapper.selectById(couponId);
		}
		LambdaQueryWrapper<CouponCode> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(CouponCode::getCouponCode, couponCode);
		CouponCode couponCode1 = couponCodeMapper.selectOne(queryWrapper);
		if (couponCode1.getIsUse() == 1) {
			throw new OperateException("优惠券已被使用");
		}
		return this.baseMapper.selectById(couponCode1.getCouponId());
	}

	/**
	 * @param userId 用户id
	 * @param couponId 优惠券id
	 */
	private void setCouponData(Integer userId, Integer couponId) {
		Coupon coupon = this.baseMapper.selectById(couponId);
		if(coupon.getEndTime() < TimeUtil.timestamp()) {
			throw new OperateException("优惠券过期，不能领取了");
		}
		if (coupon.getNumber() > 0) {
			coupon.setClaimCount(coupon.getClaimCount() + 1);
			coupon.setUpdateTime(TimeUtil.timestamp());
			this.baseMapper.updateById(coupon);
		}

		// 领取优惠券
		UserCoupon userCoupon = new UserCoupon();
		userCoupon.setUserId(userId);
		userCoupon.setCouponId(couponId);
		userCoupon.setIsDelete(GlobalConstant.NOT_DELETE);
		userCoupon.setIsUsed(GlobalConstant.NOT_DELETE);
		userCoupon.setCreateTime(TimeUtil.timestamp());
		userCoupon.setUpdateTime(TimeUtil.timestamp());
		userCoupon.setEndTime(coupon.getEndTime());
		userCouponMapper.insert(userCoupon);
	}
}
